package com.je.gateway.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * URL匹配工具类
 *
 * @author wangmm
 * @date 2020/11/5
 */
public class UrlMatcher {

    private static final String TMP_PLACEHOLDER = "@@@@@#####$$$$$";

    /**
     * 符合的正则
     */
    private final List<Pattern> includePatterns;
    /**
     * 剔除的正则
     */
    private final List<Pattern> excludePatterns;

    public UrlMatcher(String includes, String excludes) {
        this.includePatterns = valueToPatterns(includes);
        this.excludePatterns = valueToPatterns(excludes);
    }

    public UrlMatcher(List<String> includes) {
        this.includePatterns = valueToPatterns(includes);
        this.excludePatterns = new ArrayList<>();
    }

    /**
     * 初始化正则
     *
     * @param value 匹配规则
     * @return 正则集合
     */
    private List<Pattern> valueToPatterns(String value) {
        List<Pattern> patterns = new ArrayList<>();
        if (value == null) {
            return patterns;
        }
        String[] patternItems = value.split(",");
        return valueToPatterns(Arrays.asList(patternItems));
    }

    /**
     * 初始化正则
     *
     * @param patternItems 匹配规则
     * @return 正则集合
     */
    private List<Pattern> valueToPatterns(List<String> patternItems) {
        List<Pattern> patterns = new ArrayList<>();
        for (String patternItem : patternItems) {
            patternItem = patternItem.trim();
            if ("".equals(patternItem)) {
                continue;
            }

            //先将 ** 替换为临时字符串
            patternItem = patternItem.replace("**", TMP_PLACEHOLDER);
            //将 * 修改为对应的正则
            patternItem = patternItem.replace("*", "[^/]*?");
            //将临时字符串替换回 **
            patternItem = patternItem.replace(TMP_PLACEHOLDER, "**");
            //将 ** 修改为对应的正则
            patternItem = patternItem.replace("**", ".*?");
            patterns.add(Pattern.compile(patternItem));
        }

        return patterns;
    }

    /**
     * 判断是否匹配
     *
     * @param url 被校验的url
     * @return 是否匹配
     */
    public boolean matches(String url) {
        return matches(includePatterns, url) && !matches(excludePatterns, url);
    }

    private boolean matches(List<Pattern> patterns, String url) {
        for (Pattern pattern : patterns) {
            Matcher matcher = pattern.matcher(url);
            if (matcher.matches()) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        UrlMatcher matcher = new UrlMatcher("/login/**,/abc/*/*", "");
        System.out.println(matcher.matches("/abc/login/get"));

    }
}
